bounded_type.hppnamespace type_safe
{
    namespace constraints
    {
        struct dynamic_bound;
        
        template <typename T, typename Bound = dynamic_bound>
        class less;
        
        template <typename T, typename Bound = dynamic_bound>
        class less_equal;
        
        template <typename T, typename Bound = dynamic_bound>
        class greater;
        
        template <typename T, typename Bound = dynamic_bound>
        class greater_equal;
        
        //=== Open/Closed Tags ===//
        constexpr bool open = false;
        constexpr bool closed = true;
        
        template <typename T, bool LowerInclusive, bool UpperInclusive, typename LowerBound = dynamic_bound, typename UpperBound = dynamic_bound>
        class bounded;
        
        template <typename T, typename LowerBound = dynamic_bound, typename UpperBound = dynamic_bound>
        using open_interval = bounded<T, open, open, LowerBound, UpperBound>;
        
        template <typename T, typename LowerBound = dynamic_bound, typename UpperBound = dynamic_bound>
        using closed_interval = bounded<T, closed, closed, LowerBound, UpperBound>;
    }
    
    template <typename T, bool LowerInclusive, bool UpperInclusive, typename LowerBound = constraints::dynamic_bound, typename UpperBound = constraints::dynamic_bound, typename Verifier = assertion_verifier>
    using bounded_type = constrained_type<T, constraints::bounded<T, LowerInclusive, UpperInclusive, LowerBound, UpperBound>, Verifier>;
    
    inline namespace literals
    {
        template <char ... Digits>
        constexpr 'hidden' operator""_bound();
        template <char ... Digits>
        constexpr 'hidden' operator""_boundu();
    }
    
    template <typename T, typename U1, typename U2>
    constexpr 'hidden' make_bounded(T&& value, U1&& lower, U2&& upper);
    
    template <typename T, typename U1, typename U2>
    constexpr 'hidden' sanitize_bounded(T&& value, U1&& lower, U2&& upper);
    
    template <typename T, typename U1, typename U2>
    constexpr 'hidden' make_bounded_exclusive(T&& value, U1&& lower, U2&& upper);
    
    template <typename T, typename U1, typename U2>
    constexpr 'hidden' sanitize_bounded_exclusive(T&& value, U1&& lower, U2&& upper);
    
    //=== clamped_type ===//
    template <typename T, typename LowerBound, typename UpperBound, typename U>
    constexpr typename std::decay<U>::type clamp(const constraints::closed_interval<T, LowerBound, UpperBound>& interval, U&& val);
    
    struct clamping_verifier;
    
    template <typename T, typename LowerBound = constraints::dynamic_bound, typename UpperBound = constraints::dynamic_bound>
    using clamped_type = constrained_type<T, constraints::closed_interval<T, LowerBound, UpperBound>, clamping_verifier>;
    
    template <typename T, typename U1, typename U2>
    constexpr 'hidden' make_clamped(T&& value, U1&& lower, U2&& upper);
}type_safe::constraints::dynamic_boundstruct dynamic_bound
{
};Tag type to enable a dynamic bound.
type_safe::constraints::lesstemplate <typename T, typename Bound = dynamic_bound>
class less
{
public:
    using value_type = decltype(base::value);
    
    using bound_type = Bound;
    
    constexpr less(Bound = {});
    
    constexpr less(const T& bound);
    constexpr less(T&& bound) noexcept('hidden');
    
    template <typename U>
    constexpr bool operator()(const U& u) const;
    
    constexpr const value_type& get_bound() const noexcept;
};A Constraint for the ts::constrained_type.
A value is valid if it is less than some given value.
type_safe::constraints::less::less::lessconstexpr less(Bound = {});Initializes it with a static bound.
Effects: Does nothing, a static bound is not stored. It will use Bound::value as the bound.
Notes: This constructor only participates in overload resolution, if a static bound is used, i.e. Bound is not ts::constraints::dynamic_bound.
type_safe::constraints::less::less::less(1)  constexpr less(const T& bound);
(2)  constexpr less(T&& bound) noexcept('hidden');Initializes it with a dynamic bound.
Effects: Copies (1)/moves (2) the object and uses that as bound.
Notes: These constructors only participate in overload resolution, if a dynamic bound is used, i.e. Bound is ts::constraints::dynamic_bound.
type_safe::constraints::less::operator()template <typename U>
constexpr bool operator()(const U& u) const;Does the actual bounds check.
type_safe::constraints::less::get_boundconstexpr const value_type& get_bound() const noexcept;Returns: The bound.
type_safe::constraints::less_equaltemplate <typename T, typename Bound = dynamic_bound>
class less_equal
{
public:
    using value_type = decltype(base::value);
    
    using bound_type = Bound;
    
    constexpr less_equal(Bound = {});
    
    constexpr less_equal(const T& bound);
    constexpr less_equal(T&& bound) noexcept('hidden');
    
    template <typename U>
    constexpr bool operator()(const U& u) const;
    
    constexpr const value_type& get_bound() const noexcept;
};A Constraint for the ts::constrained_type.
A value is valid if it is less than or equal to some given value.
type_safe::constraints::less_equal::less_equal::less_equalconstexpr less_equal(Bound = {});Initializes it with a static bound.
Effects: Does nothing, a static bound is not stored. It will use Bound::value as the bound.
Notes: This constructor only participates in overload resolution, if a static bound is used, i.e. Bound is not ts::constraints::dynamic_bound.
type_safe::constraints::less_equal::less_equal::less_equal(1)  constexpr less_equal(const T& bound);
(2)  constexpr less_equal(T&& bound) noexcept('hidden');Initializes it with a dynamic bound.
Effects: Copies (1)/moves (2) the object and uses that as bound.
Notes: These constructors only participate in overload resolution, if a dynamic bound is used, i.e. Bound is ts::constraints::dynamic_bound.
type_safe::constraints::less_equal::operator()template <typename U>
constexpr bool operator()(const U& u) const;Does the actual bounds check.
type_safe::constraints::less_equal::get_boundconstexpr const value_type& get_bound() const noexcept;Returns: The bound.
type_safe::constraints::greatertemplate <typename T, typename Bound = dynamic_bound>
class greater
{
public:
    using value_type = decltype(base::value);
    
    using bound_type = Bound;
    
    constexpr greater(Bound = {});
    
    constexpr greater(const T& bound);
    constexpr greater(T&& bound) noexcept('hidden');
    
    template <typename U>
    constexpr bool operator()(const U& u) const;
    
    constexpr const value_type& get_bound() const noexcept;
};A Constraint for the ts::constrained_type.
A value is valid if it is greater than some given value.
type_safe::constraints::greater::greater::greaterconstexpr greater(Bound = {});Initializes it with a static bound.
Effects: Does nothing, a static bound is not stored. It will use Bound::value as the bound.
Notes: This constructor only participates in overload resolution, if a static bound is used, i.e. Bound is not ts::constraints::dynamic_bound.
type_safe::constraints::greater::greater::greater(1)  constexpr greater(const T& bound);
(2)  constexpr greater(T&& bound) noexcept('hidden');Initializes it with a dynamic bound.
Effects: Copies (1)/moves (2) the object and uses that as bound.
Notes: These constructors only participate in overload resolution, if a dynamic bound is used, i.e. Bound is ts::constraints::dynamic_bound.
type_safe::constraints::greater::operator()template <typename U>
constexpr bool operator()(const U& u) const;Does the actual bounds check.
type_safe::constraints::greater::get_boundconstexpr const value_type& get_bound() const noexcept;Returns: The bound.
type_safe::constraints::greater_equaltemplate <typename T, typename Bound = dynamic_bound>
class greater_equal
{
public:
    using value_type = decltype(base::value);
    
    using bound_type = Bound;
    
    constexpr greater_equal(Bound = {});
    
    constexpr greater_equal(const T& bound);
    constexpr greater_equal(T&& bound) noexcept('hidden');
    
    template <typename U>
    constexpr bool operator()(const U& u) const;
    
    constexpr const value_type& get_bound() const noexcept;
};A Constraint for the ts::constrained_type.
A value is valid if it is greater than or equal to some given value.
type_safe::constraints::greater_equal::greater_equal::greater_equalconstexpr greater_equal(Bound = {});Initializes it with a static bound.
Effects: Does nothing, a static bound is not stored. It will use Bound::value as the bound.
Notes: This constructor only participates in overload resolution, if a static bound is used, i.e. Bound is not ts::constraints::dynamic_bound.
type_safe::constraints::greater_equal::greater_equal::greater_equal(1)  constexpr greater_equal(const T& bound);
(2)  constexpr greater_equal(T&& bound) noexcept('hidden');Initializes it with a dynamic bound.
Effects: Copies (1)/moves (2) the object and uses that as bound.
Notes: These constructors only participate in overload resolution, if a dynamic bound is used, i.e. Bound is ts::constraints::dynamic_bound.
type_safe::constraints::greater_equal::operator()template <typename U>
constexpr bool operator()(const U& u) const;Does the actual bounds check.
type_safe::constraints::greater_equal::get_boundconstexpr const value_type& get_bound() const noexcept;Returns: The bound.
(1)  constexpr bool open = false;
(2)  constexpr bool closed = true;Tag objects to specify bounds for ts::constraints::bounded.
type_safe::constraints::boundedtemplate <typename T, bool LowerInclusive, bool UpperInclusive, typename LowerBound = dynamic_bound, typename UpperBound = dynamic_bound>
class bounded
{
public:
    using value_type = T;
    
    using lower_bound = LowerBound;
    
    using upper_bound = UpperBound;
    
    static constexpr auto lower_inclusive = LowerInclusive;
    
    static constexpr auto upper_inclusive = UpperInclusive;
    
    constexpr bounded();
    
    template <typename U1, typename U2>
    constexpr bounded(U1&& lower, U2&& upper, decltype(lower_type(std::forward<U1>(lower)), 0) = 0, decltype(upper_type(std::forward<U2>(upper)), 0) = 0);
    
    template <typename U>
    constexpr bool operator()(const U& u) const;
    
    constexpr const typename lower_type::value_type& get_lower_bound() const noexcept;
    
    constexpr const typename upper_type::value_type& get_upper_bound() const noexcept;
};A Constraint for the ts::constrained_type.
A value is valid if it is between two given bounds, LowerInclusive/UpperInclusive control whether the lower/upper bound itself is valid too.
type_safe::constraints::bounded::bounded::boundedconstexpr bounded();Initializes it with static bounds.
Effects: Does nothing, a static bound is not stored. It will use LowerBound::value as lower bound and UpperBound::value as upper bound.
Notes: This constructor does not participate in overload resolution, unless both bounds are static, i.e. not ts::constraints::dynamic_bound.
type_safe::constraints::bounded::boundedtemplate <typename U1, typename U2>
constexpr bounded(U1&& lower, U2&& upper, decltype(lower_type(std::forward<U1>(lower)), 0) = 0, decltype(upper_type(std::forward<U2>(upper)), 0) = 0);Initializes it with (mixed) dynamic bounds.
Effects: Perfectly forwards the arguments to the bounds. If a bound is static, the static member value will be used as bound, if it is dynamic, a copy created by perfectly forwarding will be stored and used as bound. \notes This constructor does not participate in overload resolution, unless the arguments are convertible to the bounds. \param 2 \exclude \param 3 \exclude
type_safe::constraints::bounded::operator()template <typename U>
constexpr bool operator()(const U& u) const;Does the bounds check.
type_safe::constraints::bounded::get_lower_boundconstexpr const typename lower_type::value_type& get_lower_bound() const noexcept;Returns: The value of the lower bound.
type_safe::constraints::bounded::get_upper_boundconstexpr const typename upper_type::value_type& get_upper_bound() const noexcept;Returns: The value of the upper bound.
type_safe::constraints::open_intervaltemplate <typename T, typename LowerBound = dynamic_bound, typename UpperBound = dynamic_bound>
using open_interval = bounded<T, open, open, LowerBound, UpperBound>;A Constraint for the ts::constrained_type.
A value is valid if it is between two given bounds but not the bounds themselves.
type_safe::constraints::closed_intervaltemplate <typename T, typename LowerBound = dynamic_bound, typename UpperBound = dynamic_bound>
using closed_interval = bounded<T, closed, closed, LowerBound, UpperBound>;A Constraint for the ts::constrained_type.
A value is valid if it is between two given bounds or the bounds themselves.
type_safe::bounded_typetemplate <typename T, bool LowerInclusive, bool UpperInclusive, typename LowerBound = constraints::dynamic_bound, typename UpperBound = constraints::dynamic_bound, typename Verifier = assertion_verifier>
using bounded_type = constrained_type<T, constraints::bounded<T, LowerInclusive, UpperInclusive, LowerBound, UpperBound>, Verifier>;An alias for ts::constrained_type that uses ts::constraints::bounded as its Constraint. \notes This is some type where the values must be in a certain interval.
type_safe::literals::operator""_bound(1)  template <char ... Digits>
     constexpr 'hidden' operator""_bound();
(2)  template <char ... Digits>
     constexpr 'hidden' operator""_boundu();Creates a static bound for ts::bounded_type.
This is a bound encapsulated in the type, so there is no overhead. You can use it for example like this ts::make_bounded(50, 0_bound, 100_bound), to bound an integer between 0 and 100.
Returns: A type representing the given value, the value has type long long (1)/unsigned long long(2).
type_safe::make_boundedtemplate <typename T, typename U1, typename U2>
constexpr 'hidden' make_bounded(T&& value, U1&& lower, U2&& upper);Creates a ts::bounded_type to a specified ts::constraints::closed_interval.
Returns: A ts::bounded_type with the given value and lower and upper bounds, where the bounds are valid values as well.
Requires: As it uses ts::assertion_verifier, the value must be valid.
Notes: If this function is passed in dynamic values of the same type as value, it will create a dynamic bound. Otherwise it must be passed static bounds.
type_safe::sanitize_boundedtemplate <typename T, typename U1, typename U2>
constexpr 'hidden' sanitize_bounded(T&& value, U1&& lower, U2&& upper);Creates a ts::bounded_type to a specified ts::constraints::closed_interval.
Returns: A ts::bounded_type with the given value and lower and upper bounds, where the bounds are valid values as well.
Throws: A ts::constrain_error if the value isn't valid, or anything else thrown by the constructor.
Notes: This is meant for sanitizing user input, using a recoverable error handling strategy.
Notes: If this function is passed in dynamic values of the same type as value, it will create a dynamic bound. Otherwise it must be passed static bounds.
type_safe::make_bounded_exclusivetemplate <typename T, typename U1, typename U2>
constexpr 'hidden' make_bounded_exclusive(T&& value, U1&& lower, U2&& upper);Creates a ts::bounded_type to a specified ts::constraints::open_interval.
Returns: A ts::bounded_type with the given value and lower and upper bounds, where the bounds are not valid values.
Requires: As it uses ts::assertion_verifier, the value must be valid.
Notes: If this function is passed in dynamic values of the same type as value, it will create a dynamic bound. Otherwise it must be passed static bounds.
type_safe::sanitize_bounded_exclusivetemplate <typename T, typename U1, typename U2>
constexpr 'hidden' sanitize_bounded_exclusive(T&& value, U1&& lower, U2&& upper);Creates a ts::bounded_type to a specified ts::constraints::open_interval, using ts::throwing_verifier.
Returns: A ts::bounded_type with the given value and lower and upper bounds, where the bounds are not valid values.
Throws: A ts::constrain_error if the value isn't valid, or anything else thrown by the constructor.
Notes: This is meant for sanitizing user input, using a recoverable error handling strategy.
Notes: If this function is passed in dynamic values of the same type as value, it will create a dynamic bound. Otherwise it must be passed static bounds.
type_safe::clamptemplate <typename T, typename LowerBound, typename UpperBound, typename U>
constexpr typename std::decay<U>::type clamp(const constraints::closed_interval<T, LowerBound, UpperBound>& interval, U&& val);Returns a copy of val so that it is in the given ts::constraints::closed_interval.
Effects: If it is not in the interval, returns the bound that is closer to the value.
type_safe::clamping_verifierstruct clamping_verifier
{
    template <typename Value, typename T, typename Bound>
    static constexpr typename std::decay<Value>::type verify(Value&& val, const constraints::less_equal<T, Bound>& p);
    
    template <typename Value, typename T, typename Bound>
    static constexpr typename std::decay<Value>::type verify(Value&& val, const constraints::greater_equal<T, Bound>& p);
    
    template <typename Value, typename T, typename LowerBound, typename UpperBound>
    static constexpr typename std::decay<Value>::type verify(Value&& val, const constraints::closed_interval<T, LowerBound, UpperBound>& interval);
};A Verifier for ts::constrained_type that clamps the value to make it valid.
It must be used together with ts::constraints::less_equal, ts::constraints::greater_equal or ts::constraints::closed_interval.
type_safe::clamping_verifier::verifytemplate <typename Value, typename T, typename Bound>
static constexpr typename std::decay<Value>::type verify(Value&& val, const constraints::less_equal<T, Bound>& p);Returns: If val is greater than the bound of p, returns the bound. Otherwise returns the value unchanged
type_safe::clamping_verifier::verifytemplate <typename Value, typename T, typename Bound>
static constexpr typename std::decay<Value>::type verify(Value&& val, const constraints::greater_equal<T, Bound>& p);Returns: If val is less than the bound of p, returns the bound. Otherwise returns the value unchanged
type_safe::clamping_verifier::verifytemplate <typename Value, typename T, typename LowerBound, typename UpperBound>
static constexpr typename std::decay<Value>::type verify(Value&& val, const constraints::closed_interval<T, LowerBound, UpperBound>& interval);Returns: Same as clamp(interval, val).
type_safe::clamped_typetemplate <typename T, typename LowerBound = constraints::dynamic_bound, typename UpperBound = constraints::dynamic_bound>
using clamped_type = constrained_type<T, constraints::closed_interval<T, LowerBound, UpperBound>, clamping_verifier>;An alias for ts::constrained_type that uses ts::constraints::closed_interval as its Constraint and ts::clamping_verifier as its Verifier. \notes This is some type where the values are always clamped so that they are in a certain interval.
type_safe::make_clampedtemplate <typename T, typename U1, typename U2>
constexpr 'hidden' make_clamped(T&& value, U1&& lower, U2&& upper);Creates a ts::clamped_type from the specified ts::constraints::closed_interval.
Returns: A ts::clamped_type with the given value and lower and upper bounds, where the bounds are valid values.
Notes: If this function is passed in dynamic values of the same type as value, it will create a dynamic bound. Otherwise it must be passed static bounds.